package cn.bsuc.crm.service.impl;


import cn.bsuc.crm.dto.LoginFormDTO;
import cn.bsuc.crm.entity.User;
import cn.bsuc.crm.entity.UserRole;
import cn.bsuc.crm.mapper.RoleMapper;
import cn.bsuc.crm.mapper.UserMapper;
import cn.bsuc.crm.mapper.UserRoleMapper;
import cn.bsuc.crm.service.UserService;
import cn.bsuc.crm.util.*;
import cn.bsuc.crm.vo.UserVO;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static cn.bsuc.crm.util.RedisConstants.*;

@Slf4j
@Service
public class UserServiceImp extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 登录
     *
     * @param loginFormDTO
     * @return
     */
    @Override
    public Result login(LoginFormDTO loginFormDTO) {
        // 1、判断用户名密码是否为空
        AssertUtils.isTrue(StrUtil.hasEmpty(loginFormDTO.getUserName()), "用户名不能为空！");
        AssertUtils.isTrue(StrUtil.hasEmpty(loginFormDTO.getUserPwd()), "密码不能为空！");
        // 2、从redis获取验证码并校验
        String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + loginFormDTO.getUuid());
        String code = loginFormDTO.getCode();
        if (cacheCode == null || !cacheCode.equals(code)) {
            return Result.fail(Code.ERROR, "验证码不正确或已过期！");
        }
        // 3、根据用户名查询用户
        User user = query().eq("user_name", loginFormDTO.getUserName())
                .eq("user_pwd", loginFormDTO.getUserPwd())
                .one();
        // 4、判断用户密码是否正确
        if (user == null) {
            // 不正确
            return Result.fail(Code.ERROR, "用户名或密码错误！");
        }
        // 5、保存token到 redis中
        // 5.1、生成token，作为登录令牌
        String token = JwtUtils.createTokenByUser(user);
        // 5.2.存储
        String tokenKey = LOGIN_TOKEN_KEY + loginFormDTO.getUserName();
        stringRedisTemplate.opsForValue().set(tokenKey, token);
        // 5.3.设置token有效期
        stringRedisTemplate.expire(tokenKey, LOGIN_TOKEN_TTL, TimeUnit.SECONDS);

        UserHolder.saveUser(user);

        // 6.封装返回对象
        Map<String, String> map = new HashMap<>();
        map.put("token", token);
        map.put("username", user.getUserName());
        map.put("id", user.getId().toString());
        // 7.返回 map
        return Result.ok(map, "登录成功");
    }

    /**
     * 修改用户密码
     *
     * @param request
     * @return
     */
    @Override
    public Result updateUserPassword(String password, HttpServletRequest request) {
        AssertUtils.isTrue(StrUtil.isEmpty(password), "新密码不能为空！");
        // 1.拿到用户 id
        String token = request.getHeader("token");
        User user = JwtUtils.getUserByToken(token);
        Integer id = user.getId();
        user.setUserPwd(password);
        // TODO 这里可以更完美
        user.setUpdateDate(null);
        return updateById(user) ? Result.ok() : Result.fail(Code.ERROR, "修改失败！");
    }

    @Override
    @Transactional
    //保存用户id及角色
    public int saveUser(User user, Integer[] roleIds) {
        LocalDateTime now = LocalDateTime.now();
        if (user.getId() == null) {
            user.setCreateDate(now);
            user.setUpdateDate(now);
            int insert = baseMapper.insert(user);
            int insert1 = userRoleMapper.insertUserRole(user.getId(), roleIds);
            if (insert >= 1 && insert1 >= 1) {
                return 1;
            } else {
                return 0;
            }
        } else {
            user.setUpdateDate(now);
            QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
            objectQueryWrapper.eq("id", user.getId());
            int i = baseMapper.updateByPrimaryKeySelective(user);
            int i1 = userRoleMapper.delectByUserId(user.getId());
            int i2 = userRoleMapper.insertUserRole(user.getId(), roleIds);
            if (i1 > 0 && i2 > 0) {
                return 1;
            } else {
                return 0;
            }
        }
    }

    //用户的多字段查询
    @Override
    public Page<User> selectByParams(User user, Integer pageNo, Integer pageSize) {
        Page<User> objectPage = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<User> objectLambdaQueryWrapper = new LambdaQueryWrapper<User>();
        if (!StringUtils.isBlank(user.getUserName())) {
            objectLambdaQueryWrapper.like(User::getUserName, user.getUserName());
        }
        if (!StringUtils.isBlank(user.getEmail())) {
            objectLambdaQueryWrapper.like(User::getEmail, user.getEmail());
        }
        if (!StringUtils.isBlank(user.getPhone())) {
            objectLambdaQueryWrapper.like(User::getPhone, user.getPhone());
        }

        Page<User> userPage = baseMapper.selectPage(objectPage, objectLambdaQueryWrapper);

        return userPage;
    }

    //用户查询分页
    @Override
    public Page<User> selectAllUser(Integer pageNo, Integer pageSize) {
        Page<User> objectPage = new Page<>(pageNo, pageSize);
        Page<User> userPage = baseMapper.selectPage(objectPage, null);
        return userPage;
    }

    //通过用户id查其角色
    @Override
    public UserVO selectAllUserRole(Integer userId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        queryWrapper.eq("id", userId);
        User user = baseMapper.selectOne(queryWrapper);

        QueryWrapper<UserRole> queryWrapper1 = new QueryWrapper();
        queryWrapper1.eq("user_id", userId);
        List<UserRole> userRoles = userRoleMapper.selectList(queryWrapper1);
        UserVO userVO = new UserVO();
        userVO.setId(user.getId());
        userVO.setUserName(user.getUserName());
        userVO.setEmail(user.getEmail());
        userVO.setPhone(user.getPhone());
        userVO.setTrueName(user.getTrueName());
        userVO.setUserPwd(user.getUserPwd());
        ArrayList<Integer> objects1 = new ArrayList<>();
        for (UserRole r : userRoles) {
            objects1.add(r.getRoleId());
        }

        userVO.setRoleId(objects1);
        return userVO;
    }

    //删除一个用户及角色
    @Override
    @Transactional
    public int deleteUserAndRole(Integer userId) {
        int i = baseMapper.deleteById(userId);
        int i1 = userRoleMapper.delectByUserId(userId);
        if (i > 0 && i1 > 0) {
            return 1;
        }
        return 0;
    }

    //批量删除用户及角色
    @Override
    public int deleteSomeUser(Integer[] userId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", userId);
        List<Integer> integers = Arrays.asList(userId);
        baseMapper.deleteBatchIds(Arrays.asList(userId));
        for (Integer u : userId) {
            userRoleMapper.delectByUserId(u);
        }
        return 1;
    }

}
